///////////////////////////////////////////
//                                       //
//          UPX X.XX OEP FINDER          //
//                                       //
//   supports EXEs & DLLs in x64 & x32   //
//                                       //
///////////////////////////////////////////
// Prepared by: Blitzkrieg
// Date       : 4th July 2023
// Tested on  :
//
// Release  |      Target       
// -----------------------------
//          |  64bit  |  32bit  
// -----------------------------
// 1.20     | -       | EXE 
// 1.24     | -       | EXE 
// 1.25     | -       | EXE 
// 2.02     | -       | EXE/DLL 
// 2.03     | -       | EXE/DLL 
// 3.06     | -       | EXE/DLL 
// 3.07     | -       | EXE/DLL 
// 3.08     | -       | EXE/DLL 
// 3.09     | -       | EXE/DLL 
// 3.91     | -       | EXE/DLL 
// 3.95     | EXE/DLL | EXE/DLL 
// 3.96     | EXE/DLL | EXE/DLL 
// 4.00     | EXE/DLL | EXE/DLL 
// 4.01     | EXE/DLL | EXE/DLL 
// 4.02     | EXE/DLL | EXE/DLL 
///////////////////////////////////////////
// Notes:
// - use "dbclear" command manually when
//   script keeps throwing errors, then
//   reload target into x64dbg. Don't use
//   it when starting-up x64dbg or it will
//   delete your Entry Point Breakpoint
//   causing more problems!
// - this script makes use of labels
//   instead of conventional comments,
//   that's because labels won't interfere
//   with your comments. Also labelclear
//   won't delete your personal comments.
///////////////////////////////////////////

//START AT THE ENTRY POINT!

call DisableBreakpoints

//Finding a long unconditional jump
mov $address,cip
notlongunconditionaljump:
find $address+1,"E9"
mov $address,$result
cmp cip,dis.imm($address) //test for jump pointing to an address above CIP
jb notlongunconditionaljump
cmp mod.base(cip)+mem.size(mod.base(cip)),dis.imm($address) //test for jump pointing to an address below base address of the current module 
ja notlongunconditionaljump
bp $address
erun
bc cip
sti

//Halting at OEP
cmt cip,"OEP Found :)"
log "OEP for UPX found at: {a:cip}"
guiupdateenable
d cip

call TimeToDump
ret



///////////////////////////////////////////
// Tools
// Prepared by: Blitzkrieg
///////////////////////////////////////////

//Disables all kinds of breakpoints
DisableBreakpoints:
bd //use dbclear manually when error thrown here
bphd
bpmd
bpddll
DisableExceptionBPX
labelclear (small addition for preventing label collusions)
EnableLog
//guiupdatedisable (for faster script execution)
ret

//Displays a confirmation window for dumping PE file with Scylla
TimeToDump:
msgyn "Successfully found OEP! Wanna use Scylla to dump the PE file?"
cmp 0,$result
je noscylla
scylla
noscylla:
ret
